import os;
import pypinyin
from pypinyin import pinyin, lazy_pinyin
import cv2
import numpy as np

def processing(img_path):
    img = cv2.imread(img_path)
    img = cv2.resize(img, (512,512), interpolation=cv2.INTER_CUBIC)
#     out = cv2.GaussianBlur(img, (3, 3),1.3) # 使用python自带的高斯滤波
    kernel = np.array([[1,2,1],[2,4,2],[1,2,1]])/16
    out = cv2.filter2D(img, -1 , kernel=kernel)  # 二维滤波器
    out = cv2.cvtColor(out, cv2.COLOR_BGR2LAB)
    return out

def qua2com(Q):
#     a1 = complex(Q[:,:,0],Q[:,:,1])
#     a2 = complex(Q[:,:,2],Q[:,:,3])
    a1 = Q[:,:,0]+Q[:,:,1]*1j;
    a2 = Q[:,:,2]+Q[:,:,3]*1j;
    A = [[a1, a2] ,[-np.conj(a2), np.conj(a1)]]
    return A

def QSVD(Q):
    A = qua2com(Q)
    U, s, V = np.linalg.svd(A)
    return s

def image_feature(image):
    """
    input: image_LAB
    output: feature_vetor
    """
    q1 = np.zeros((64,1))
    q2 = np.zeros((64,1))
    temp = np.concatenate((np.zeros((512,512,1)), image), axis=2)
    flag = 0
    for i in range(0,512,64):
        for j in range(0,512,64):
            image_block = temp[i:i+64,j:j+64,:]
            s = QSVD(image_block)
            q1[flag] = np.diagonal(s,offset=0)[0][0]
            q2[flag] = np.diagonal(s,offset=0)[1][0]
            flag += 1
    return q1,q2

def hash_general(q1,q2):
    x = (q1-np.mean(q1))/np.std(q1)
    y = (q2-np.mean(q2))/np.std(q2)
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    d = np.sqrt((x-x_mean)**2 + (y-y_mean)**2)
    d = np.floor(d*100+0.5)
    return d.reshape(1,-1)

def image_hash(img_path):
    image = processing(img_path)
    q1, q2 = image_feature(image)
    d = hash_general(q1, q2)
    return d

def dis_image(d1, d2):
    return np.sqrt(sum(sum((d1 - d2) ** 2)))

def rename(path):
    """
    将文件夹中的所有中文文件转换为英文文件
    """
    filelist = os.listdir(path)  # 该文件夹下所有的文件（包括文件夹）

    for files in filelist:  # 遍历所有文件
        Olddir = os.path.join(path, files);  # 原来的文件路径
        if os.path.isdir(Olddir):  # 如果是文件夹则跳过
            continue;

        filename = os.path.splitext(files)[0];  # 获取文件名
        # 把文件名里的汉字转换成其首字母
        filename1 = pinyin(filename, style=pypinyin.FIRST_LETTER)
        # 创建一个空列表
        filename2 = []
        for ch in filename1:
            filename2.extend(ch)
        # 把列表转换成没有间隔的字符串，因为文件名要以字符串形式存在
        filenameToStr = ''.join(filename2)

        filetype = os.path.splitext(files)[1];  # 文件扩展名

        Newdir = os.path.join(path, filenameToStr + filetype);  # 新的文件名

        os.rename(Olddir, Newdir);  # 重命名

def dis_similar_dir(path):
    # 计算相同类型图片的距离
    dir_rotation = os.listdir(path)
    dis_similar = []
    for i in dir_rotation:
        if os.path.splitext(i)[1] == ".bmp":
#             print(os.path.join(path, i)) # 用于查看路径是否有中文
            h1 = image_hash(os.path.join(path, i))
            dir_temp = os.path.join(path,os.path.splitext(i)[0])
            for j in os.listdir(dir_temp):
#                 print(os.path.join(dir_temp,j)) # 用于查看路径是否有中文
                h2 = image_hash(os.path.join(dir_temp,j))
                dis_similar.append(dis_image(h1,h2))
    return dis_similar
            
def dis_different_dir(path):
    # 计算不同图片的距离
    dirs = os.listdir(path)
    image_set_list = []
    for i in tqdm(range(500), ncols = 50):
        h1 = image_hash(os.path.join(path, dirs[i]))
        for j in tqdm(range(i+1,len(dirs)),ncols = 50,mininterval = 60):
#             print(index,os.path.join(path, dirs[j])) # 用于查看路径是否有中文
            h2 = image_hash(os.path.join(path, dirs[j]))
            image_set_list.append(dis_image(h1,h2))
    return image_set_list

def my_auc(image_similar, image_different):
    sum1 = len(image_similar)
    sum2 = len(image_different)
    tpr = []
    fpr = []
    threshold_max = (max(max(image_similar), max(image_different)) //20 + 1) * 20
    for threshold in range(0,threshold_max,20):
        tpr_number = 0
        fpr_number = 0
        for i in image_similar[0]:
            if i < threshold:
                tpr_number += 1
        for j in image_different[0]:
            if j < threshold:
                fpr_number += 1
        tpr.append(tpr_number/sum1)
        fpr.append(fpr_number/sum2)
    return integrate.trapezoid(tpr,fpr)